package com.dark.sys.service.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.dark.common.repository.hibernate.HibernateDao;
import com.dark.common.utils.BeanUtils;
import com.dark.sys.entity.Resource;
import com.dark.sys.entity.RoleResource;
import com.dark.sys.service.RoleResourceService;
import com.dark.sys.web.dto.ResourceDto;
import com.dark.sys.web.dto.RoleResourceDto;


@Service
public class RoleResourceServiceImpl implements RoleResourceService {
	
	@Autowired
	private HibernateDao<RoleResource, Integer> basedaoRoleResource ;
	
	@Autowired
	private HibernateDao<Resource, Integer> basedaoResource ;
	
	@Override
	public void add(RoleResourceDto dto) {
		String roleIds = dto.getRoleIds() ;
		if(null != roleIds && !"".equals(roleIds)) {
			String[] split = roleIds.split(",") ;
			for (String roleId : split) {
				RoleResource entity = new RoleResource() ;
				BeanUtils.copyNotNullProperties(dto, entity);
				entity.setRoleId(Integer.parseInt(roleId)) ;
				
				//先删除原有的角色资源权限
				deleteByRoleId(Integer.parseInt(roleId));
				
				if(null != dto.getResourceIds() && !"".equals(dto.getResourceIds().trim())) {
					this.basedaoRoleResource.save(entity) ;
				}
			}
		}
		
	}
	private void deleteByRoleId(Integer roleId) {
		this.basedaoRoleResource.executeSQL("delete from sys_role_resource where roleId=?", new Object[]{roleId}) ;
	}

	@Override
	public RoleResourceDto getOneByRoleId(Integer roleId) {
		String queryString = "select t.* from sys_role_resource t where t.roleId=?" ;
		return (RoleResourceDto) this.basedaoRoleResource.findUniqueSQL(queryString, new Object[]{roleId}, RoleResourceDto.class, false) ;
	}
	
	
	@Override
	public List<ResourceDto> operationResourceTree(ResourceDto dto) {
		List<ResourceDto> tg = new ArrayList<ResourceDto>() ;
		
		String queryString = "select t.* from sys_resource t where 1=1 " ;
		
		Map<String, Object> alias = new HashMap<String, Object>() ;
		if(null != dto && dto.getId() != null) {
			queryString += " and t.pid=:pid" ;
			alias.put("pid", dto.getId()) ;
		} else {
			queryString += " and t.pid is null and t.menuId=:menuId" ;
			alias.put("menuId", dto.getMenuId()) ;
		}
		
		List<ResourceDto> resources = this.basedaoResource.findListSQL(queryString, alias, ResourceDto.class, false) ;
		
		for (ResourceDto resourceDto : resources) {
			tg.add(recursiveResourceOPerations(resourceDto)) ;
		}
		return tg;
	}
	
	private ResourceDto recursiveResourceOPerations(ResourceDto dto) {
		String queryChild = "select t.* from sys_resource t where t.pid=?" ;
		List<ResourceDto> childs = this.basedaoResource.findListSQL(queryChild, new Object[]{dto.getId()}, ResourceDto.class, false) ;
		
		if(null != childs && !childs.isEmpty()) {
			List<ResourceDto> children = new ArrayList<ResourceDto>() ;
			List<ResourceDto> opers = new ArrayList<ResourceDto>() ;
			
			for (ResourceDto child : childs) {
				if(child.getType()) {
					opers.add(child) ;
				} else {
					children.add(recursiveResourceOPerations(child)) ;
				}
			}
			dto.setOperations(opers);
			dto.setChildren(children);
		}
		return dto;
	}
	@Override
	public Set<Integer> getByRoleToResource(String roleIds) {
		Set<Integer> filterResourceIds = new HashSet<Integer>() ;
		
		if(null != roleIds) {
			StringBuffer queryString = new StringBuffer("SELECT t.* FROM sys_role_resource t WHERE t.roleId in(:ids) ") ;
			Map<String, Object> alias = new HashMap<String, Object>() ;
			alias.put("ids", roleIds.split(",")) ;
			
			List<RoleResourceDto> roleResource = this.basedaoResource.findListSQL(queryString.toString(), alias, RoleResourceDto.class, false) ;
			for (RoleResourceDto rr : roleResource) {
				String[] split = rr.getResourceIds().split(",") ;
				for (String s : split) {
					filterResourceIds.add(Integer.parseInt(s)) ;
				}
			}
		}
		return filterResourceIds;
	}
	
}
